package boot.example.tcp.server.netty;


import boot.example.tcp.server.netty.codec.NettyDecoder;
import boot.example.tcp.server.netty.codec.NettyEncoder;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

/**
 * 通道初始化
 * 蚂蚁舞
 */
@ChannelHandler.Sharable
public class BootNettyChannelInitializer<SocketChannel> extends ChannelInitializer<Channel> {

    public static long READ_TIME_OUT = 60;

    public static long WRITE_TIME_OUT = 60;

    public static long ALL_TIME_OUT = 60;

    //     Netty 提供的编码器
    // • StringEncoder，对字符串数据进行编码
    // • ObjectEncoder，对 Java 对象进行编码


    //     Netty 本身自带的 ObjectDecoder 和 ObjectEncoder 可以用来实现 POJO 对象或各种业务对象的编码和解码，底层使用的仍是 Java 序列化技术 , 而Java 序列化技术本身效率就不高，存在如下问题
    // • 无法跨语言
    // • 序列化后的体积太大，是二进制编码的 5 倍多。
    // • 序列化性能太

    @Override
    protected void initChannel(Channel ch) throws Exception {

        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new IdleStateHandler(READ_TIME_OUT, WRITE_TIME_OUT, ALL_TIME_OUT, TimeUnit.SECONDS));

        // 编码格式
        pipeline.addLast(new NettyEncoder());
        //解码格式
        pipeline.addLast(new NettyDecoder());

        // 数据分割符
        String delimiterStr = "##@##";
        ByteBuf delimiter = Unpooled.copiedBuffer(delimiterStr.getBytes());
        // 使用自定义处理拆包/沾包，并且每次查找的最大长度为1024字节
        pipeline.addLast(new DelimiterBasedFrameDecoder(1024, delimiter));

        // 加入事件回调处理器
        pipeline.addLast(new NettyServerHandler());

    }

}
